home *** CD-ROM | disk | FTP | other *** search
- /*
- * This program simulates a simple toy with many many variations.
- *
- * Compile with -DARROWKEYS if your curses library understands about
- * arrow keys (and your keyboards have them).
- * Compile with -DNOSIGNAL if your machine does not support the signal
- * function to catch ctrl-C.
- * Compile with "-DDIECHAR='<somechar>'" if you would like the program
- * to exit gracefully when <somechar> is typed. All the quotes in and
- * around this argument are necessary. The double quotes prevent the
- * shell from stripping the single quotes. Instead of '<somechar' you
- * can also type the ascii value of the key. If you do so, the double
- * quotes are not needed.
- *
- * The copyright message is there to prevent uncontrolled spreading of
- * a zillion different versions.
- *
- * You can mail your improvements and suggestions to me. I may include
- * them in a future version of the program.
- *
- * I do not guarantee the fitness of this program for any purpose.
- * USE IT AT YOUR OWN RISK.
- *
- * Peter Knoppers - knop@duteca.UUCP
- * Bilderdijkhof 59
- * 2624 ZG Delft
- * The Netherlands
- *
- *
- * The following lines are put in the compiled program by the C compiler
- * where they can be found by programs such as (Bsd) strings.
- */
- char *this_is = "puzzle15 V2.0 Feb 24 1989";
- char *author0 = "(C) Copyright 1985, 1988, 1989 Peter Knoppers";
- char *author1 = "Arrow keys added by Paul Lew 1988";
- char *author2 = "Clock added by Bo Kullmar 1988";
- char *author3 = "Select-tile method suggested by Larry Hastings 1988";
- char *authorx = "Additions merged by Peter Knoppers";
- char *release1 = "Permission to use and redistribute unmodified ";
- char *release2 = "copies with source is granted to everyone";
- char *release3 = "Distribution of modified copies is NOT allowed";
-
- #include <curses.h>
- #ifndef NOSIGNAL
- #include <signal.h>
- #endif
- #include <ctype.h>
-
- #ifndef DIECHAR
- #define DIECHAR 999 /* any non-ASCII value will do */
- #endif
- #define DEFSIZE 4 /* default size of board */
- #define BLANK 0
- #define UNSPECIFIED (-1)
- /* classification of arguments */
- #define MOVEMETHOD 1
- #define CURSORMETHOD 2
- #define FACEMETHOD 3
- /* magic values are required to be different, no other restrictions apply */
- /* magic values for Movemethods */
- #define MOVEBLANK 4
- #define MOVETILE 5
- #define SELECTTILE 6
- /* magic values for Cursormethods */
- #define VIKEYS 7
- #ifdef ARROWKEYS
- #define ARROWK 8
- #endif
- #define NUMBERKEYS 9
- #define FACEKEYS 10
- #define KEYS 11
- /* magic values for Facemethods */
- #define NUMBERFACES 12
- #define ALPHAFACES 13
- #define NUMBERALPHAFACES 14
- #define ALPHANUMBERFACES 15
- #define FACES 16
-
- unsigned long Time_start;
- int Movecnt = 0;
-
- #ifdef __STDC__
- void *malloc (unsigned); /* to satisfy lint */
- long time (long *);
- #else
- char *malloc (); /* to satisfy lint */
- long time ();
- #endif
-
- int Sizex = UNSPECIFIED; /* x-size of the board */
- int Sizey = UNSPECIFIED; /* y-size of the board */
- int Size2; /* total surface of the board */
- int Movemethod = UNSPECIFIED;
- int Cursormethod = UNSPECIFIED;
- int Facemethod = UNSPECIFIED;
- char *Movename; /* name of the selected Movemethod */
- char *Cursorname; /* name of the selected Cursormethod */
- char *Cursorkeys; /* the user-defined Cursorkeys */
- char *Facename; /* name of the selected Facemethod */
- char *Facechars; /* the user-defined tile-faces */
- int Up; /* key-codes for cursor movements */
- int Down;
- int Left;
- int Right;
- int Newpos; /* new position for empty field */
- char *Myname; /* name used to invoke this program */
- /*
- * All possible keyword arguments are listed in the Argopts table.
- * This is done in order to
- * - ensure that every keyword appears at only one place in the program
- * (this makes the program easier to modify/maintain)
- * - put most of the knowledge about incompatible arguments in one place
- * instead of scattering it all over the program.
- * - simplify the argument parser
- * (I haven't been completely succesfull in this respect...)
- */
- struct argtablemember
- {
- char *a_name; /* what the user types */
- int a_type; /* what kind of spec. it is */
- int a_magic; /* magic value */
- } Argopts[] =
- {
- {
- "moveblank", MOVEMETHOD, MOVEBLANK
- },
- {
- "movetile", MOVEMETHOD, MOVETILE
- },
- { /* SELECTTILE must be before FACEKEYS */
- "selecttile", MOVEMETHOD, SELECTTILE
- },
- {
- "vikeys", CURSORMETHOD, VIKEYS
- },
- #ifdef ARROWKEYS
- {
- "arrowkeys", CURSORMETHOD, ARROWK
- },
- #endif
- {
- "numberkeys", CURSORMETHOD, NUMBERKEYS
- },
- {
- "facekeys", CURSORMETHOD, FACEKEYS
- },
- {
- "keys", CURSORMETHOD, KEYS
- },
- {
- "numberfaces", FACEMETHOD, NUMBERFACES
- },
- {
- "alphafaces", FACEMETHOD, ALPHAFACES
- },
- {
- "numberalphafaces", FACEMETHOD, NUMBERALPHAFACES
- },
- {
- "alphanumberfaces", FACEMETHOD, ALPHANUMBERFACES
- },
- {
- "faces", FACEMETHOD, FACES
- },
- {
- (char *) 0, 0, 0
- }
- };
-
- die () /* nice exit on ctrl-C */
- {
- #ifndef NOSIGNAL
- signal (SIGINT, SIG_IGN); /* ignore ctrl-C */
- #endif
- mvprintw (LINES - 1, 0, "Goodbye. ");
- clrtoeol ();
- refresh ();
- endwin (); /* shutdown curses, restore ttymode */
- exit (0);
- }
-
- main (argc, argv) /* scan the arguments, call game() */
- char **argv;
- {
- struct argtablemember *atmp;/* to walk Argopts table */
- int swap; /* to revers directions */
-
- Myname = *argv; /* save this for usage () */
- /*
- * scan the arguments
- */
- while (*++argv != ((char *) 0))
- { /* walk argument list */
- for (atmp = Argopts; atmp -> a_name != (char *) 0; atmp++)
- { /* scan the keyword list */
- if (strcmp (*argv, atmp -> a_name) == 0)
- { /* found keyword */
- switch (atmp -> a_type)
- {
- case MOVEMETHOD:
- if (Movemethod != UNSPECIFIED)
- conflict (Movename, atmp -> a_name);
- Movename = atmp -> a_name;
- Movemethod = atmp -> a_magic;
- break;
- case CURSORMETHOD:
- if (Cursormethod != UNSPECIFIED)
- conflict (Cursorname, atmp -> a_name);
- Cursorname = atmp -> a_name;
- Cursormethod = atmp -> a_magic;
- if (atmp -> a_magic == KEYS)
- {
- if ((Cursorkeys = *++argv) == (char *) 0)
- novalue (*--argv);/* never returns */
- if (strlen (Cursorkeys) != 4)
- {
- printf ("%s need 4 cursorkeys\n",
- Cursorname);
- usage ();
- }
- }
- break;
- case FACEMETHOD:
- if (Facemethod != UNSPECIFIED)
- conflict (Facename, atmp -> a_name);
- Facename = atmp -> a_name;
- Facemethod = atmp -> a_magic;
- if (atmp -> a_magic == FACES)
- if ((Facechars = *++argv) == (char *) 0)
- novalue (*--argv);
- break;
- default:
- printf ("aargh: bad switch (atmp -> a_type = %d)\n",
- atmp -> a_type);
- exit (1);
- }
- break;
- }
- }
- if (atmp -> a_name == (char *) 0)/* not a keyword */
- if (isdigit (**argv) && (Sizex == UNSPECIFIED))
- { /* it's a boardsize specification */
- if (sscanf (*argv, "%dx%d", &Sizex, &Sizey) != 2)
- if (sscanf (*argv, "%d", &Sizex) == 1)
- Sizey = Sizex;
- else
- {
- printf ("bad argument %s\n", *argv);
- usage ();
- }
- }
- else /* it's garbage */
- {
- printf ("bad argument %s\n", *argv);
- usage ();
- }
- }
-
- /*
- * insert default values
- */
- if (Sizex == UNSPECIFIED)
- Sizex = Sizey = DEFSIZE;
-
- if (Cursormethod == UNSPECIFIED)
- { /* find first CURSORMETHOD in Argopts */
- for (atmp = Argopts; atmp -> a_name != (char *) 0; atmp++)
- if (atmp -> a_type == CURSORMETHOD)
- break;
- if (atmp -> a_name == (char *) 0)
- {
- printf ("aargh: can't find default Cursormethod\n");
- exit (1);
- }
- Cursormethod = atmp -> a_magic;
- Cursorname = atmp -> a_name;
- }
-
- if (Facemethod == UNSPECIFIED)
- { /* find first FACEMETHOD in Argopts */
- for (atmp = Argopts; atmp -> a_name != (char *) 0; atmp++)
- if (atmp -> a_type == FACEMETHOD)
- break;
- if (atmp -> a_name == (char *) 0)
- {
- printf ("aargh: can't find default Facemethod\n");
- exit (1);
- }
- Facemethod = atmp -> a_magic;
- Facename = atmp -> a_name;
- }
-
- if (Movemethod == UNSPECIFIED)
- if (Cursormethod == FACEKEYS)
- Movemethod = SELECTTILE;/* by implication */
- else
- { /* find first MOVEMETHOD in Argopts */
- for (atmp = Argopts; atmp -> a_name != (char *) 0; atmp++)
- if (atmp -> a_type == MOVEMETHOD)
- break;
- if (atmp -> a_name == (char *) 0)
- {
- printf ("aargh: can't find default Movemethod\n");
- exit (1);
- }
- Movemethod = atmp -> a_magic;
- Movename = atmp -> a_name;
- }
-
- if ((Cursormethod == FACEKEYS) && (Movemethod != SELECTTILE))
- conflict (Cursorname, Movename);/* does not return */
- switch (Cursormethod)
- {
- case VIKEYS:
- Up = 'k';
- Down = 'j';
- Left = 'h';
- Right = 'l';
- break;
- #ifdef ARROWKEYS
- case ARROWK:
- Up = KEY_UP;
- Down = KEY_DOWN;
- Left = KEY_LEFT;
- Right = KEY_RIGHT;
- break;
- #endif
- case NUMBERKEYS:
- Up = '8';
- Down = '2';
- Left = '4';
- Right = '6';
- break;
- case FACEKEYS:
- Up = 1000; /* values must not correspond to any ASCII */
- Down = 1001; /* value, otherwise no restrictions */
- Left = 1002;
- Right = 1003;
- break;
- case KEYS:
- Up = Cursorkeys[0];
- Down = Cursorkeys[1];
- Left = Cursorkeys[2];
- Right = Cursorkeys[3];
- break;
- default:
- printf ("aargh: bad switch (Cursormethod = %d)\n",
- Cursormethod);
- exit (1);
- }
-
- if (Movemethod == MOVETILE)
- { /* revers cursor directions */
- swap = Up;
- Up = Down;
- Down = swap;
- swap = Left;
- Left = Right;
- Right = swap;
- }
-
- Size2 = Sizex * Sizey; /* surface area of the board */
-
- switch (Facemethod)
- {
- case NUMBERFACES:
- if (Size2 <= 10) /* tiles can be labeled with 1 char */
- {
- Facechars = "123456789";
- Facemethod = NUMBERALPHAFACES;
- }
- break;
- case ALPHAFACES:
- Facechars = "abcdefghijklmnopqrstuvwxyz";
- break;
- case NUMBERALPHAFACES:
- Facechars = "0123456789abcdefghijklmnopqrstuvwxyz";
- break;
- case ALPHANUMBERFACES:
- Facechars = "abcdefghijklmnopqrstuvwxyz0123456789";
- break;
- }
-
- if ((Size2 - 1) > ((Facemethod == NUMBERFACES) ? 99 :
- strlen (Facechars)))
- {
- printf ("sorry, too many tiles - not enough labels\n");
- exit (0);
- }
- if ((Sizex < 2) || (Sizey < 2))
- {
- printf ("sorry, board is too small for a non-trivial game\n");
- exit (0);
- }
-
- /*
- * Initialize the curses screen handling functions
- */
- #ifndef NOSIGNAL
- signal (SIGINT, SIG_IGN); /* protect this critical section */
- #endif
- initscr ();
- crmode ();
- noecho ();
- #ifdef ARROWKEYS
- keypad (stdscr, TRUE);
- #endif
- #ifndef NOSIGNAL
- signal (SIGINT, die); /* die() knows how to restore ttymode */
- #endif
- /*
- * From now on use die() to exit the program, otherwise the
- * ttymode will not be restored.
- *
- * Now that curses has been initialized we can check whether the board
- * fits on the screen.
- */
- if (Sizex > (COLS - 1) / 5) /* COLS works only after initscr() */
- {
- mvprintw (LINES - 2, 0,
- "sorry, your screen is not wide enough\n");
- die ();
- }
- if (Sizey > (LINES - 4) / 2)
- {
- mvprintw (LINES - 2, 0,
- "sorry, your screen is not tall enough\n");
- die ();
- }
-
- game (); /* play the game */
-
- mvprintw (LINES - 2, 0,
- "You've reached the solution in %d moves.\n", Movecnt);
- die (); /* restore ttymode and exit */
- }
-
- usage ()
- {
- int curtype = UNSPECIFIED;
- int prevtype = UNSPECIFIED;
- char *selecttilename = (char *) 0;
- struct argtablemember *atmp;/* to walk Argopts table */
-
- printf ("usage: %s [<width[x<height>]] %s",
- Myname, "[movemethod] [cursormethod] [facemethod]\n");
- for (atmp = Argopts; atmp -> a_name != (char *) 0; atmp++)
- {
- if (atmp -> a_magic == SELECTTILE)
- selecttilename = atmp -> a_name;
- if (atmp -> a_type != curtype)
- {
- curtype = atmp -> a_type;
- if (curtype == MOVEMETHOD)
- printf ("possible movemethods:\n");
- if (curtype == CURSORMETHOD)
- printf ("possible cursormethods:\n");
- if (curtype == FACEMETHOD)
- printf ("possible facemethods:\n");
- }
- switch (atmp -> a_magic)
- {
- case KEYS:
- printf ("\t\t%s <up><down><left><right>", atmp -> a_name);
- break;
- case FACES:
- printf ("\t\t%s <facecharacters>", atmp -> a_name);
- break;
- case FACEKEYS:
- if (selecttilename == (char *) 0)
- {
- printf ("aargh: can't find string for SELECTTILE\n");
- exit (1);
- }
- printf ("\t\t%-20.20s (implies movemethod %s)",
- atmp -> a_name, selecttilename);
- break;
- default:
- printf ("\t\t%-20.20s", atmp -> a_name);
- break;
- }
- if (curtype != prevtype)
- printf (" (this is default)\n");
- else
- printf ("\n");
- prevtype = curtype;
- }
- exit (0);
- }
-
- conflict (word1, word2)
- char *word1;
- char *word2;
- {
- printf ("You may not specify both %s and %s\n", word1, word2);
- usage ();
- }
-
- novalue (word)
- char *word;
- {
- printf ("%s requires an argument\n", word);
- usage ();
- }
-
- game () /* initialize board, execute moves */
- {
- register int i, j; /* generally used indices and counters */
- int *board; /* pointer to malloc-ed board */
- int empty; /* position of empty field */
- int swap; /* used to swap two tiles */
- int nswap = 0; /* to determine reachability */
- int steps; /* number of tiles that move */
- int unchanged = 0; /* used to indicate that board has changed */
- int cursorx; /* to save cursorposition while */
- int cursory; /* printing error messages */
- int m; /* move, first character / direction */
- int m2; /* second character of move */
- /*
- * Set up the board and shuffle the tiles
- */
- board = (int *) malloc ((unsigned) (Size2 * sizeof (int)));
- if (board == NULL)
- {
- printf ("aargh: malloc failed\n");
- die ();
- }
- srand ((int) time ((long) 0));/* initialize random number generator */
- for (i = 1; i < Size2; i++) /* put tiles on the board in their */
- board[i - 1] = i; /* final positions */
- for (i = Size2 - 2; i > 0; i--)/* permutate tiles */
- {
- j = rand () % i;
- swap = board[i];
- board[i] = board[j];
- board[j] = swap;
- }
- /*
- * Check that final position can be reached from current permutation
- */
- for (i = 0; i < Size2 - 1; i++)
- for (j = 0; j < i; j++)
- if (board[j] > board[i])
- nswap++;
- if ((nswap % 2) != 0) /* this position is unreachable */
- { /* swap two adjacent tiles */
- swap = board[1];
- board[1] = board[0];
- board[0] = swap;
- }
- empty = Size2 - 1; /* empty field starts in lower right */
- board[empty] = BLANK; /* corner */
- Newpos = empty;
- Time_start = time ((long *) 0);/* start the clock */
-
- while (1) /* until final position is reached */
- {
- if (unchanged == 0) /* the board must be (re-)printed */
- {
- printboard (board); /* also puts cursor at Newpos */
- unchanged++; /* the board on the screen is up to date */
- /*
- * Check if final position is reached
- */
- for (i = 0; i < Size2 - 1; i++)
- if (board[i] != i + 1)
- break; /* final position is not yet reached */
- if (i == Size2 - 1) /* all tiles are in final positions */
- return; /* game ends */
- }
- /*
- * Let the user make a move
- */
- m = getch ();
- if (m == DIECHAR)
- die ();
- if (Movemethod == SELECTTILE)
- {
- if (Cursormethod == FACEKEYS)
- {
- if (Facemethod == NUMBERFACES)
- {
- if (!isdigit (m))
- {
- getyx (stdscr, cursory, cursorx);
- mvprintw (LINES - 1, 0,
- "use one of the keys");
- for (i = 0; (i <= Size2) && (i < 10); i++)
- printw (" %d", i);
- clrtoeol ();
- move (cursory, cursorx);
- refresh ();
- continue;
- }
- if ((m - '0') > (Size2 / 10))
- m -= '0';
- else /* we need a second digit */
- {
- m = (m - '0') * 10;
- m2 = getch ();
- if (m == DIECHAR)
- die ();
- if ((!isdigit (m2)) || (m + m2 - '0' >= Size2))
- {
- getyx (stdscr, cursory, cursorx);
- mvprintw (LINES - 1, 0,
- "use one of the keys");
- for (i = 0; (i < Size2 % 10) && (i + m < Size2);
- i++)
- printw (" %d", i);
- clrtoeol ();
- move (cursory, cursorx);
- refresh ();
- continue;
- }
- m += m2 - '0';
- }
- /*
- * find out where this tile is on the board
- */
- for (Newpos = 0; Newpos < Size2; Newpos++)
- if (board[Newpos] == m)
- break;/* found tile */
- if (Newpos == Size2)/* no tile with face m */
- {
- mvprintw (LINES - 2, 0,
- "aargh: can't find tile %d on board\n", m);
- die ();
- }
- }
- else
- {
- /*
- * Facemethod != NUMBERFACES
- * This means that a single keystroke identifies the
- * tile that is to be moved.
- */
- for (Newpos = 0; Newpos < Size2; Newpos++)
- if (board[Newpos] > 0)
- if (Facechars[board[Newpos] - 1] == m)
- break;/* found tile */
- if (Newpos == Size2)
- {
- getyx (stdscr, cursory, cursorx);
- mvprintw (LINES - 1, 0,
- "use one of the keys ");
- for (i = 0; (i < Size2 - 1) && (i < 30); i++)
- printw ("%c", Facechars[i]);
- if (i < Size2 - 1)
- printw ("...");
- clrtoeol ();
- move (cursory, cursorx);
- refresh ();
- continue;
- }
- }
- }
- else /* Cursormethod != FACEKEYS */
- {
- if (m == Up)
- {
- if (Newpos >= Sizex)
- Newpos -= Sizex;
- unchanged = 0;/* board must be reprinted */
- continue;
- }
- if (m == Down)
- {
- if (Newpos + Sizex < Size2)
- Newpos += Sizex;
- unchanged = 0;
- continue;
- }
- if (m == Left)
- {
- if ((Newpos % Sizex) != 0)
- Newpos--;
- unchanged = 0;
- continue;
- }
- if (m == Right)
- {
- if (((Newpos + 1) % Sizex) != 0)
- Newpos++;
- unchanged = 0;
- continue;
- }
- /*
- * If a key not in the set { Up, Down, Left, Right } was
- * typed we fall through and try to move the empty field to
- * Newpos.
- */
- }
- /*
- * The user has indicated a new location for the empty field.
- * The new position of the empty field in the array board is in
- * Newpos.
- * We must now check that the new position is on the same row
- * or the same column as the current position and we must
- * determine how many tiles must be moved.
- */
- if (Newpos == empty)
- continue; /* nothing changed */
- steps = 0;
- if (Newpos > empty)
- {
- if ((empty % Sizex + Newpos - empty) < Sizex)
- {
- m = Right;
- steps = Newpos - empty;
- }
- else
- if (((Newpos - empty) % Sizex) == 0)
- {
- m = Down;
- steps = (Newpos - empty) / Sizex;
- }
- }
- else
- {
- if (empty % Sizex + Newpos - empty >= 0)
- {
- m = Left;
- steps = empty - Newpos;
- }
- else
- if (((empty - Newpos) % Sizex) == 0)
- {
- m = Up;
- steps = (empty - Newpos) / Sizex;
- }
- }
- if (steps == 0)
- {
- getyx (stdscr, cursory, cursorx);
- mvprintw (LINES - 1, 0,
- "tile must be in same row as empty field\n");
- move (cursory, cursorx);
- refresh ();
-
- continue;
- }
- }
- else /* Movemethod is MOVEBLANK or MOVETILE */
- steps = 1; /* one step per move */
- /*
- * m should now be one of the four directions, but it may be an
- * illegal key. This can not happen if Movemethod == SELECTTILE.
- *
- * steps indicates how many tiles are to be moved
- */
- if ((m != Up) && (m != Down) && (m != Left) && (m != Right))
- {
- getyx (stdscr, cursory, cursorx);
- #ifdef ARROWKEYS
- if (Cursormethod == ARROWK)
- mvprintw (LINES - 1, 0,
- "Use the arrow keys for up, down, left and right");
- else
- #endif
- if (Movemethod == MOVETILE)
- {
- mvprintw (LINES - 1, 0,
- "use %c for up, %c for down, ", Down, Up);
- printw ("%c for left and %c for right", Right, Left);
- }
- else
- {
- mvprintw (LINES - 1, 0,
- "use %c for up, %c for down, ", Up, Down);
- printw ("%c for left and %c for right", Left, Right);
- }
- clrtoeol ();
- move (cursory, cursorx);
- refresh ();
- continue;
- }
- /*
- * m contains the direction to move
- * steps contains the number of tiles to move
- * Apply the move to the board.
- */
- if (m == Up)
- if (empty >= Sizex)
- while (steps-- > 0)
- {
- board[empty] = board[empty - Sizex];
- board[empty - Sizex] = BLANK;
- empty -= Sizex;
- Movecnt++;
- }
- if (m == Down)
- if (empty + Sizex < Size2)
- while (steps-- > 0)
- {
- board[empty] = board[empty + Sizex];
- board[empty + Sizex] = BLANK;
- empty += Sizex;
- Movecnt++;
- }
- if (m == Left)
- if ((empty % Sizex) != 0)
- while (steps-- > 0)
- {
- board[empty] = board[empty - 1];
- board[empty - 1] = BLANK;
- empty--;
- Movecnt++;
- }
- if (m == Right)
- if (((empty + 1) % Sizex) != 0)
- while (steps-- > 0)
- {
- board[empty] = board[empty + 1];
- board[empty + 1] = BLANK;
- empty++;
- Movecnt++;
- }
- if (steps == 1) /* you ran into a wall */
- {
- getyx (stdscr, cursory, cursorx);
- mvprintw (LINES - 1, 0,
- "Your can't cross that wall\n");
- clrtoeol ();
- move (cursory, cursorx);
- refresh ();
- continue;
- }
- if (steps != -1) /* something is very wrong */
- {
- mvprintw (LINES - 2, 0,
- "aargh: couldn't move enough tiles (steps = %d)\n",
- steps);
- die ();
- }
- Newpos = empty;
- unchanged = 0; /* the board must be reprinted */
- }
- }
-
- printboard (board)
- int *board;
- {
- register int i, j;
- int tilewidth;
- unsigned long time_used;
- unsigned minutes;
- unsigned seconds;
- unsigned long time_now;
-
- tilewidth = ((Facemethod == NUMBERFACES) && (Size2 > 10)) ? 5 : 4;
- mvprintw ((LINES - 4 - 2 * Sizey) / 2,
- (COLS - 1 - tilewidth * Sizex) / 2,
- "+"); /* print top edge of board */
- for (j = 0; j < Sizex; j++)
- if (tilewidth == 5)
- printw ("----+");
- else
- printw ("---+");
- for (i = 0; i < Sizey; i++)
- {
- mvprintw ((LINES - 4 - 2 * Sizey) / 2 + i * 2 + 1,
- (COLS - 1 - tilewidth * Sizex) / 2, "| ");
- for (j = 0; j < Sizex; j++)
- if (tilewidth == 5)
- if (board[Sizex * i + j] != BLANK)
- if ((Size2 > 9) && (Cursormethod == FACEKEYS) &&
- (board[Sizex * i + j] <= Size2 / 10))
- printw ("%02d | ", board[Sizex * i + j]);
- else
- printw ("%2d | ", board[Sizex * i + j]);
- else
- printw (" | ");
- else
- if (board[Sizex * i + j] != BLANK)
- printw ("%c | ", Facechars[board[Sizex * i + j] - 1]);
- else
- printw (" | ");
- mvprintw ((LINES - 4 - 2 * Sizey) / 2 + i * 2 + 2,
- (COLS - 1 - tilewidth * Sizex) / 2, "+");
- for (j = 0; j < Sizex; j++)
- if (tilewidth == 5)
- printw ("----+");
- else
- printw ("---+");
- }
- mvprintw (LINES - 1, 0, "\n");/* erase error messages */
- /*
- * Update the clock
- */
- time_now = time ((long *) 0);
- time_used = time_now - Time_start;
- minutes = time_used / 60;
- seconds = time_used % 60;
- mvprintw (LINES - 3, 0, "Time used: %02d min %02d sec Move: %d",
- minutes, seconds, Movecnt);
- /*
- * Put cursor on the position indicated by Newpos
- */
- move ((LINES - 4 - 2 * Sizey) / 2 + (Newpos / Sizex) * 2 + 1,
- (COLS - 1 - tilewidth * Sizex) / 2 +
- (Newpos % Sizex) * tilewidth + tilewidth / 2);
- refresh (); /* put all this on the screen */
- }
-